using System;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;
using System.Text;

using Kenly.DBFramework.Gateway;

namespace Kenly.DBFramework.Reflection
{
    /// <summary>
    /// 
    /// </summary>
    public static class AttributeUtility
    {
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="propertyInfo"></param>
        /// <returns></returns>
        public static T GetCustomAttribute<T>(PropertyInfo propertyInfo)
        {
            object[] customAttributes = propertyInfo.GetCustomAttributes(typeof(T), true);
            if (customAttributes.Length > 0)
            {
                return (T)customAttributes[0];
            }
            return default(T);
        }

        #region Column

        public static ColumnAttribute GetColumnAttribute(PropertyInfo propertyInfo)
        {
            object[] customAttributes = propertyInfo.GetCustomAttributes(typeof(ColumnAttribute), true);
            ColumnAttribute parameterAttribute = null;
            foreach (object attr in customAttributes)
            {
                parameterAttribute = attr as ColumnAttribute;
                if (parameterAttribute != null)
                {
                    return parameterAttribute;
                }
            }
            return null;
        }

        public static ColumnAttribute GetColumnAttribute(Type type, string propertyName)
        {
            if (type == null || string.IsNullOrEmpty(propertyName))
            {
                return null;
            }
            foreach (PropertyInfo propertyInfo in type.GetProperties())
            {
                if (string.Equals(propertyInfo.Name, propertyName))
                {
                    return GetColumnAttribute(propertyInfo);
                }
            }
            return null;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="propertyInfo"></param>
        /// <returns></returns>
        public static string GetColumnName(PropertyInfo propertyInfo)
        {
            ColumnAttribute columnAttribute = GetColumnAttribute(propertyInfo);
            if (columnAttribute == null)
            {
                return "";
            }

            if (!string.IsNullOrEmpty(columnAttribute.ColumnName))
            {
                return columnAttribute.ColumnName;
            }
            else
            {
                return propertyInfo.Name;
            }
        }

        #endregion


        #region Table

        public static TableAttribute GetTableAttribute(Type type)
        {
            object[] customAttributes = type.GetCustomAttributes(typeof(TableAttribute), true);
            TableAttribute tableAttribute = null;
            foreach (object attr in customAttributes)
            {
                tableAttribute = attr as TableAttribute;
                if (tableAttribute != null)
                {
                    return tableAttribute;
                }
            }
            return null;
        }

        //public static string ReflectTableName(object entity)
        //{
        //    TableAttribute attr = GetTableAttribute(entity.GetType());
        //    if (attr != null)
        //    {
        //        return attr.TableName;
        //    }
        //    return entity.GetType().Name;
        //}

        public static string ReflectTableName(Type type)
        {
            TableAttribute attr = GetTableAttribute(type);
            if (attr != null)
            {
                return attr.TableName;
            }
            return type.Name;
        }

        #endregion

        public static AssociationAttribute GetAssociationAttribute(PropertyInfo propertyInfo)
        {
            object[] customAttributes = propertyInfo.GetCustomAttributes(typeof(AssociationAttribute), true);
            AssociationAttribute relationAttribute = null;
            foreach (object attr in customAttributes)
            {
                relationAttribute = attr as AssociationAttribute;
                if (relationAttribute != null)
                {
                    return relationAttribute;
                }
            }
            return null;
        }


        public static ProcedureAttribute GetProcedureAttribute(Type type)
        {
            object[] customAttributes = type.GetCustomAttributes(typeof(ProcedureAttribute), true);
            ProcedureAttribute attribute = null;
            foreach (object attr in customAttributes)
            {
                attribute = attr as ProcedureAttribute;
                if (attribute != null)
                {
                    return attribute;
                }
            }
            return null;
        }

        public static ParameterAttribute GetParameterAttribute(PropertyInfo propertyInfo)
        {
            object[] customAttributes = propertyInfo.GetCustomAttributes(typeof(ParameterAttribute), true);
            ParameterAttribute attribute = null;
            foreach (object attr in customAttributes)
            {
                attribute = attr as ParameterAttribute;
                if (attribute != null)
                {
                    return attribute;
                }
            }
            return null;
        }

        //public static List<ParameterAttribute> GetParameterAttributes(Type type)
        //{
        //    List<ParameterAttribute> parameterAttributes = new List<ParameterAttribute>();
        //    ParameterAttribute attr = null;
        //    foreach (PropertyInfo propertyInfo in type.GetProperties())
        //    {
        //        attr = GetParameterAttribute(propertyInfo);
        //        if (attr != null)
        //        {
        //            parameterAttributes.Add(attr);
        //        }
        //    }
        //    return parameterAttributes;
        //}

        /// <summary>
        /// 
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static Dictionary<string,ParameterAttribute> GetParameterAttributes(Type type)
        {
            Dictionary<string, ParameterAttribute> parameterAttributes = new Dictionary<string, ParameterAttribute>();
            ParameterAttribute attr = null;
            foreach (PropertyInfo propertyInfo in type.GetProperties())
            {
                attr = GetParameterAttribute(propertyInfo);
                if (attr != null)
                {
                    parameterAttributes.Add(propertyInfo.Name,attr);
                }
            }
            return parameterAttributes;
        }

    }
}
